package gins

import (
	"bytes"
	"fmt"
	"github.com/bytedance/sonic"
	"github.com/gin-gonic/gin/binding"
	"io"
	"net/http"
)

var SonicBindingJSON = soincJsonBinding{}

// 可以自定义soinc配置或者添加插件
type soincJsonBinding struct {
}

func (soincJsonBinding) Name() string { return "json" }
func (soincJsonBinding) Bind(req *http.Request, obj interface{}) error {
	if req == nil || req.Body == nil {
		return fmt.Errorf("invalid request")
	}
	return decodeJSONSonic(req.Body, obj)
}
func (soincJsonBinding) BindBody(body []byte, obj interface{}) error {
	return decodeJSONSonic(bytes.NewReader(body), obj)
}

func decodeJSONSonic(r io.Reader, obj interface{}) error {
	config := sonic.Config{}

	if binding.EnableDecoderUseNumber {
		config.UseNumber = true
	}
	if binding.EnableDecoderDisallowUnknownFields {
		config.DisallowUnknownFields = true
	}

	decoder := config.Froze().NewDecoder(r)
	if err := decoder.Decode(obj); err != nil {
		return err
	}
	return validate2(obj)
}

func validate2(obj interface{}) error {
	if binding.Validator == nil {
		return nil
	}
	return binding.Validator.ValidateStruct(obj)
}
